package edu.ynu.se.xiecheng.achitectureclass.service;

import edu.ynu.se.xiecheng.achitectureclass.common.service.LogicService;
import edu.ynu.se.xiecheng.achitectureclass.dao.UserDao;
import edu.ynu.se.xiecheng.achitectureclass.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Service
public class UserService extends LogicService<UserDao, User, Long> {
    public UserService(@Autowired UserDao userDao) {
        super(userDao);
    }

    @Transactional
    public Boolean register(User user) {
        if (user == null || user.getPassword() == null || user.getUsername() == null) {
            throw new IllegalArgumentException("User, Username and Password cannot be null");
        }

        if (getDAO().findUserByUsername(user.getUsername()) != null) {
            throw new IllegalArgumentException("Username already exists");
        }

        user.setPassword(hashPassword(user.getPassword()));
        
        try {
            User savedUser = super.POST(user);
            return savedUser != null;
        } catch (Exception e) {
            throw new RuntimeException("Registration failed: " + e.getMessage(), e);
        }
    }

    @Transactional
    public Boolean login(String username, String password) {
        User user = getDAO().findUserByUsername(username);
        if (user != null) {
            return user.getPassword().equals(password);
        }
        return false;
    }

    private String hashPassword(String password) {
        try{
            MessageDigest digest = MessageDigest.getInstance("SHA-512");
            byte[] encodedhash = digest.digest(password.getBytes());
            return byteToHex(encodedhash);
        }catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Could not hash password",e);
        }
    }

    private String byteToHex(byte[] hash) {
        StringBuilder hexString = new StringBuilder(2*hash.length);
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
}
